#ifndef ERROR_H
#define ERROR_H

#include "ObjLib_global.h"
#include "log.h"


#define THROW_ERROR(err_name,message) \
    throw err_name(message,__FILE__,__FUNCTION__,__LINE__); \

#define LOG_ERROR(error) \
    Log::Instance()->writeError(error.message()); \


enum ErrorType
{
    ANY_ERROR,//基础错误

    SYSTEM_ERROR,//系统
    MEMORY_ERROR,//内存
    IO_ERROR,//输入(出)

    DOMAIN_ERROR,//值域

    LICENSE_ERROR,//许可
    RUNTIME_ERROR,//运行时(App)
    LIBRARY_ERROR,//对象库
};

class OBJLIB_EXPORT Error : public std::exception
{
protected:
    Error(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1);

public:
    QString message() const;
    QString typeName()	const { return mTypeName; }
    ErrorType type() const { return mType; }

protected:
    QString mMessage;
    ErrorType mType;
    QString mTypeName;
    QString mFileName;
    QString mFuncName;
    QString mLineName;
};

class OBJLIB_EXPORT SystemError : public Error
{
public:
    SystemError(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1)
        : Error(msg, filename, funcname, line)
    {
        mType = SYSTEM_ERROR;
        mTypeName = QObject::tr("System Error");
    }
};

class OBJLIB_EXPORT MemoryError : public Error
{
public:
    MemoryError(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1)
        : Error(msg, filename, funcname, line)
    {
        mType = SYSTEM_ERROR;
        mTypeName = QObject::tr("Memory Error");
    }
};

class OBJLIB_EXPORT IoError : public Error
{
public:
    IoError(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1)
        : Error(msg, filename, funcname, line)
    {
        mType = IO_ERROR;
        mTypeName = QObject::tr("IO Error");
    }
};

class OBJLIB_EXPORT DomainError : public Error
{
public:
    DomainError(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1)
        : Error(msg, filename, funcname, line)
    {
        mType = DOMAIN_ERROR;
        mTypeName = QObject::tr("Domain Error");
    }
};

class OBJLIB_EXPORT LicenseError : public Error
{
public:
    LicenseError(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1)
        : Error(msg, filename, funcname, line)
    {
        mType = LICENSE_ERROR;
        mTypeName = QObject::tr("License Error");
    }
};

class OBJLIB_EXPORT RuntimeError : public Error
{
public:
    RuntimeError(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1)
        : Error(msg, filename, funcname, line)
    {
        mType = RUNTIME_ERROR;
        mTypeName = QObject::tr("Runtime Error");
    }
};

class OBJLIB_EXPORT LibraryError : public Error
{
public:
    LibraryError(const QString& msg, std::string filename = "", std::string funcname = "", int line = -1)
        : Error(msg, filename, funcname, line)
    {
        mType = LIBRARY_ERROR;
        mTypeName = QObject::tr("Library Error");
    }
};





//class OBJLIB_EXPORT Error : public std::exception
//{
//public:
//    Error(int code, std::string filename = "", std::string funcname = "", int line = -1);

//public:

//    //static Error& createError(int code);

//    static void addError(int code,QString text);

//    QString message();
//    int code() const;
//private:
//    inline static QMap<int, QString>& instance();

//    int mCode;
//    QString mFileName;
//    QString mFuncName;
//    QString mLineName;
//};

//#define ADD_ERROR(code,text) \
//    Error::addError(code,text);\

//#define THROW_ERROR(code) \
//    throw Error(code,__FILE__,__FUNCTION__,__LINE__); \

//#define LOG_ERROR(error) \
//    Log::Instance()->writeError(error.message()); \


#endif // ERROR_H
